package com.zzj.utils;

import com.alibaba.fastjson2.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.zzj.entity.User;
import lombok.extern.log4j.Log4j2;

import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

@Log4j2
public class JWTUtil {
    // jwt 加解密类型
    public static final String SECRET_KEY = "blog-zzj"; //秘钥
    public static final long TOKEN_EXPIRE_TIME = 12 *60* 60  * 1000; //token过期时间 ms  12h
    public static final long REFRESH_TOKEN_EXPIRE_TIME = 60*60*24 ; //refreshToken过期时间 s 24h
    public static final String BLACK_KEY ="redis-Token黑名单";
    private static final String ISSUER = "blog-zWesley"; //签发人


    /**
     * 生成签名
     */
    public static String generateToken(User user){
        Date now = new Date();
        Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY); //算法
        String token = JWT.create()
                .withIssuer(ISSUER) //签发人
                .withIssuedAt(now) //签发时间
                .withExpiresAt(new Date(now.getTime() + TOKEN_EXPIRE_TIME)) //过期时间
                .withClaim("user", JSON.toJSONString(user))//保存身份标识
                .withClaim("id", user.getId())
                .withClaim("username", user.getUsername())
                .withClaim("email", user.getEmail())
                .withClaim("role", user.getRole())
                .withClaim("avatar", user.getAvatar())
                .sign(algorithm);
        return token;
    }

    /**
     * 验证token
     */
    public static boolean verify(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY); //算法
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(ISSUER)
                    .build();
            verifier.verify(token);
            return true;
        } catch (JWTVerificationException e) {
            // 如果 JWT 验证失败，记录验证失败的原因，然后返回 false
            Logger.getLogger(JWTUtil.class.getName()).log(Level.WARNING, "JWT 验证失败: " + e.getMessage());
            return false;
        }
    }

    public static User getUser(String token) {
        return JSON.parseObject(getClaim(token, "user"), User.class);
    }
    /**
     * 从 token 获取用户名
     * 返回空字符串表示获取失败
     */
    public static String getUsername(String token) {
        return getClaim(token, "username");
    }

    /**
     * 从 token 获取角色
     * 返回空字符串表示获取失败
     */
    public static String getRole(String token) {
        return getClaim(token, "role");
    }
    public static String getClaim(String token, String claimName) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            Claim claim = jwt.getClaim(claimName);
            if (claim.isNull()) {
                // 如果声明不存在，记录日志并返回空字符串
                Logger.getLogger(JWTUtil.class.getName()).log(Level.WARNING, "无法获取声明 " + claimName + ", 因为 JWT 不包含该声明");
                return "";
            }
            return claim.asString();
        } catch (JWTDecodeException e) {
            // 如果解码 JWT 失败，记录原因并返回空字符串
            Logger.getLogger(JWTUtil.class.getName()).log(Level.WARNING, "无法从 JWT 获取声明 " + claimName + ": " + e.getMessage());
            return "";
        }
    }

}